/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.gestionabsences.form;

import com.gestionabsences.beans.WebUser;
import com.gestionabsences.config.DAOFactory;
import com.gestionabsences.database.ToolsRequest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author matt
 */
public class FormConnection {
    public static final String CHAMP_LOGIN = "login";
    public static final String CHAMP_PASSWORD = "password";
    public static final String CHAMP_KIND_OF_USER = "kindOfUser";
    public static final String CHAMP_ERREUR = "erreur";
    
    private final int MIN_LENGTH_LOGIN = 4;
    private final int MIN_LENGTH_PASSWORD = 4;
    
    private static final String PASSWORD_PATTERN = "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{6,20})";
    
    private Map<String, String> erreurs;
    
    private Connection connexion;
    
    public FormConnection(DAOFactory dao) {
	erreurs = new HashMap<String, String>();
	
	try {
	    connexion = dao.getConnection();
	} catch (SQLException e) {
	    setErreur( CHAMP_ERREUR, e.getMessage() );
	}
    }
    
    public Map<String, String> getErreurs() {
        return erreurs;
    }

    public WebUser creerWebUser( HttpServletRequest request ) {
        String login = getValeurChamp(request, CHAMP_LOGIN );
        String password = getValeurChamp(request, CHAMP_PASSWORD );
        String kindOfUser = getValeurChamp(request, CHAMP_KIND_OF_USER );
        WebUser.TypeUser typeUser = null;
	
        try {
            validationLogin( login );
        } catch ( Exception e ) {
            setErreur( CHAMP_LOGIN, e.getMessage() );
        }

        try {
            validationPassword( password );
        } catch ( Exception e ) {
            setErreur( CHAMP_PASSWORD, e.getMessage() );
        }

        try {
            validationTypeUser( kindOfUser );
            if(kindOfUser.compareTo("ETUDIANT") == 0) {
                typeUser = WebUser.TypeUser.STRING_ONE;
            } else if (kindOfUser.compareTo("ENSEIGNANT") == 0) {
                typeUser = WebUser.TypeUser.STRING_TWO;
            } else if (kindOfUser.compareTo("SECRETAIRE") == 0) {
                typeUser = WebUser.TypeUser.STRING_THREE;
            } else {
                typeUser = WebUser.TypeUser.STRING_FOUR;
            }
        } catch ( Exception e ) {
            setErreur( CHAMP_KIND_OF_USER, e.getMessage() );
        }
	
	WebUser user = null;
	
        if ( erreurs.isEmpty() ) {
	    if( !checkLoginAndPassword(login, password, typeUser) ) {
		setErreur(CHAMP_ERREUR, "Le login ou le mot de passe ou le type d'utilisateur selectionné est incorrect.");
	    }
	    
	    user = completeProfile(typeUser, login, password);
	}
	
	ToolsRequest.close(connexion);
	
	return user;
    }

    private boolean checkLoginAndPassword(String login, String password, WebUser.TypeUser type) {
	
	String typeUser;
	
	if(type == WebUser.TypeUser.STRING_ONE) {
	    typeUser = "Etudiant";
	} else if(type == WebUser.TypeUser.STRING_TWO) {
	    typeUser = "Enseignant";
	} else if(type == WebUser.TypeUser.STRING_THREE) {
	    typeUser = "Secretaire";
	} else {
	    typeUser = "Admin";
	}
	
	String sql_select_login_pwd = "SELECT email FROM " + typeUser + " WHERE email = ? AND md5sumpassword = MD5(?);";
	String email = null;
	PreparedStatement preparedStatement = null;
	ResultSet resultSet = null;
	try {
	    preparedStatement = ToolsRequest.prepareRequest( this.connexion, sql_select_login_pwd, false, login + "@gmail.com", password );
	    
	    //preparedStatement = connexion.prepareStatement(sql_select_login_pwd);
	    //preparedStatement.setString( 1, login + "@gmail.com" );
	    //preparedStatement.setString( 2, password );
	    
	    //setErreur(CHAMP_ERREUR, preparedStatement.toString());
	    
	    resultSet = preparedStatement.executeQuery();

	    while ( resultSet.next() ) {
		 email = resultSet.getString( "email" );
		 //setErreur(CHAMP_ERREUR, email);
	    }
	} catch(SQLException e) {}
	finally {
	    ToolsRequest.close(preparedStatement, resultSet);
	}
	return (email != null) ? true : false;
    }
    
    private WebUser completeProfile(WebUser.TypeUser type, String login, String password ) {
	String typeUser;
	
	String email = null;
	String affectation = null;
	String primaryKey = null;
	String nom = null;
	String prenom = null;
	
	if(type == WebUser.TypeUser.STRING_ONE) {
	    typeUser = "Etudiant";
	} else if(type == WebUser.TypeUser.STRING_TWO) {
	    typeUser = "Enseignant";
	} else if(type == WebUser.TypeUser.STRING_THREE) {
	    typeUser = "Secretaire";
	} else {
	    typeUser = "Admin";
	}
	
	String sql_select = "SELECT * FROM getInformations" + typeUser + "(?);";
	//String SQL_SELECT_LIST_MATIERES = "SELECT CAST(id_matiere AS VARCHAR(10)) id_matiere, matiere FROM getListeMatieresEtudiant(?);";
	
	PreparedStatement preparedStatement = null;
	ResultSet resultSet = null;
	try {
	    preparedStatement = ToolsRequest.prepareRequest( this.connexion, sql_select, false, login + "@gmail.com");
	    
	    //setErreur(CHAMP_ERREUR, preparedStatement.toString());
	    
	    resultSet = preparedStatement.executeQuery();

	    while ( resultSet.next() ) {
		 email = resultSet.getString( "email" );
		 primaryKey = resultSet.getString( "identifiant" );
		 affectation = resultSet.getString( "affectation" );
		 nom = resultSet.getString( "nom" );
		 prenom = resultSet.getString( "prenom" );
		 //setErreur(CHAMP_ERREUR, email + primaryKey + affectation + nom + prenom);
	    }
	    
	    /*preparedStatement = ToolsRequest.prepareRequest( this.connexion, SQL_SELECT_LIST_MATIERES, false, primaryKey);
	    setErreur(CHAMP_ERREUR, preparedStatement.toString() );
	    resultSet = preparedStatement.executeQuery();
	    
	    String id_matiere = null;
	    String matiere = null;
	    
	    while ( resultSet.next() ) {
		id_matiere = resultSet.getString( "id_matiere" );
		matiere = resultSet.getString( "matiere" );
		setErreur(CHAMP_ERREUR, id_matiere + " " + matiere );
	    }*/
	    
	} catch(SQLException e) {}
	finally {
	    ToolsRequest.close(preparedStatement, resultSet);
	}
	
	return new WebUser(login, password, type, email, primaryKey, affectation, nom, prenom);
    }
    
    private void validationLogin( String login ) throws Exception {
        if ( login != null ) {
            if ( login.length() < MIN_LENGTH_LOGIN ) {
                throw new Exception( "Ce login n'est pas valide." );
            }
        } else {
            throw new Exception( "Merci d'entrer le login." );
        }
    }

    private void validationPassword( String password ) throws Exception {
        if ( password != null )
        {
            if(password.length() < MIN_LENGTH_PASSWORD || !password.matches(PASSWORD_PATTERN)) {
                throw new Exception( "Le mot de passe saisie n'est pas correct." );
            }
        } else {
            throw new Exception("Merci d'entrer le mot de passe.");
        }
    }

    private void validationTypeUser( String type ) throws Exception {
        if ( type != null) {
            if ( 0 != type.compareTo( WebUser.TypeUser.STRING_ONE.toString() ) && 0 != type.compareTo( WebUser.TypeUser.STRING_TWO.toString() ) && 0 != type.compareTo( WebUser.TypeUser.STRING_THREE.toString() ) && 0 != type.compareTo( WebUser.TypeUser.STRING_FOUR.toString() )) {
                throw new Exception( "Le type d'utilisateur n'est pas valide." );
            }
        } else {
            throw new Exception( "Merci de spécifier quel genre d'utilisateur vous êtes." );
        }
    }

    /*
     * Ajoute un message correspondant au champ spécifié à la map des erreurs.
     */
    private void setErreur( String champ, String message ) {
	String previous = erreurs.get(champ);
	erreurs.put( champ, ( (previous == null) ? "" : previous ) + message );
    }

    /*
     * Méthode utilitaire qui retourne null si un champ est vide, et son contenu
     * sinon.
     */
    private static String getValeurChamp( HttpServletRequest request, String nomChamp ) {
        String valeur = request.getParameter( nomChamp );
        if ( valeur == null || valeur.trim().length() == 0 ) {
            return null;
        } else {
            return valeur;
        }
    }
}
